package com.cloudbroker.bcs.platform.ltb.middle.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.cloudbroker.bcs.platform.ltb.middle.util.ssl.SSLClient;

/**
 * Created by xuyn15828 on 2016/3/18.
 */
public class HttpsUtil {
    private static final Logger logger = LoggerFactory.getLogger(HttpsUtil.class);

    public static JSONObject post(String url, String postData, String charset) {
        JSONObject json = new JSONObject();
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = new SSLClient();
            httpPost = new HttpPost(url);
            StringEntity se = new StringEntity(new String(postData.getBytes("UTF-8") , "UTF-8"), "utf-8");
            se.setContentType("text/json");
            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json;charset=utf-8"));
            httpPost.setEntity(se);
            logger.info("\nclient ===> wechat : " + url + "\n" + postData);
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, charset);
                }
            }
            logger.info("\nwechat ===> client : " + result );
            return JSONObject.parseObject(result);
        } catch (Exception e) {
            logger.error("\nsend https post error " , e);
        }
        return json;
    }

    public static JSONObject get(String url) {
        JSONObject json = new JSONObject();
        HttpClient httpClient = null;
        String result = null;
        try {
            httpClient = new SSLClient();
            HttpGet get = new HttpGet(url);
            logger.info("\nclient ===> wechat : " + url );
            HttpResponse response = httpClient.execute(get);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity,"utf-8");
                }
            }
            json = JSONObject.parseObject(result);
            logger.info("\nwechat ===> client : " + result );
        } catch (Exception e) {
            logger.error("\nsend https get error " , e);
        }
        return json;
    }

    public static CloseableHttpClient createSSLClientDefault() throws KeyStoreException, NoSuchAlgorithmException {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(
                    null, new TrustStrategy() {
                        @Override
                        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                            return true;
                        }
                    }
            ).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }

    public static String doHttpsPost(String url,Map<String,Object> map){
        try {
            CloseableHttpClient client = createSSLClientDefault();
            List<NameValuePair> pairs = null;
            if (map != null && !map.isEmpty()) {
                pairs = new ArrayList<NameValuePair>(map.size());
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    String value =  entry.getValue().toString().trim();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
            }

            HttpPost post = new HttpPost(url);
            if (pairs != null && pairs.size() > 0) {
                post.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
            }
            CloseableHttpResponse response = client.execute(post);
            return acquireResult(response,post);
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String doXmlPost(String url,String xml){
        HttpPost post = new HttpPost(url);

        try {
            CloseableHttpClient client = createSSLClientDefault();
            StringEntity entity = new StringEntity(xml);
            post.setEntity(entity);
            post.setHeader("Content-Type", "text/xml;charset=UTF-8");
            CloseableHttpResponse httpResponse = client.execute(post);
            return acquireResult(httpResponse,post);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return null;
    }

    /***
     * 获取Http Get/Post请求中返回的数据
     * @param response	服务器返回response
     * @param requestBase HttpGet/HttpPost 对象
     *
     * @return String 服务器返回数据
     * */
    private static String acquireResult(CloseableHttpResponse response , HttpRequestBase requestBase) throws IOException {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            requestBase.abort();
            throw new RuntimeException("HttpClient,error status code :" + statusCode);
        }
        HttpEntity entity = response.getEntity();
        String result = null;
        if (entity != null) {
            result = EntityUtils.toString(entity, "utf-8");
        }
        EntityUtils.consume(entity);
        return result;
    }

}
